package org.jeecg.modules.c.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.c.entity.DActiveAlarm;
import org.jeecg.modules.c.entity.MSC;
import org.jeecg.modules.c.entity.MSU;
import org.jeecg.modules.c.service.IDActiveAlarmService;

import org.jeecg.modules.c.service.IMSCService;
import org.jeecg.modules.c.service.IMSUService;
import org.jeecg.modules.client.ChannelManager;
import org.jeecg.modules.client.NettyClient;
import org.jeecg.modules.enmu.AttributeLength;
import org.jeecg.modules.enmu.MessageTypeEnum;
import org.jeecg.modules.utils.SendMessageUtils;
import org.jeecg.modules.vo.Message;
import org.jeecg.modules.vo.TcpLoginRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Date;

/**
 * @Description: 实时告警管理
 * @Author: jeecg-boot
 * @Date: 2024-11-05
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "TCP接口")
@RestController
@RequestMapping("/c/tcpcontroller")
public class TcpClientController extends JeecgController<DActiveAlarm, IDActiveAlarmService> {
    @Autowired
    private IDActiveAlarmService dActiveAlarmService;
    @Autowired
    private ChannelManager channelManager;
    @Autowired
    private IMSCService mSCService;

    /**
     * 分页列表查询
     *
     * @param dActiveAlarm
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "实时告警管理-分页列表查询")
    @ApiOperation(value = "实时告警管理-分页列表查询", notes = "实时告警管理-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(DActiveAlarm dActiveAlarm, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
        QueryWrapper<DActiveAlarm> queryWrapper = QueryGenerator.initQueryWrapper(dActiveAlarm, req.getParameterMap());
        Page<DActiveAlarm> page = new Page<DActiveAlarm>(pageNo, pageSize);
        IPage<DActiveAlarm> pageList = dActiveAlarmService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param dActiveAlarm
     * @return
     */
    @AutoLog(value = "实时告警管理-添加")
    @ApiOperation(value = "实时告警管理-添加", notes = "实时告警管理-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody DActiveAlarm dActiveAlarm) {
        dActiveAlarmService.save(dActiveAlarm);
        return Result.OK("添加成功！");
    }


    /**
     * 添加
     *
     * @param
     * @return
     */
    @AutoLog(value = "tcp建立连接")
    @ApiOperation(value = "tcp建立连接", notes = "tcp建立连接")
    @PostMapping(value = "/link")
    public Result<?> add(@RequestBody TcpLoginRequest loginRequest) throws InterruptedException {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //获取激活管道
        NettyClient.start(msc);
        return Result.OK("登录成功");
    }


    /**
     * 添加
     *
     * @param
     * @return
     */
    @AutoLog(value = "tcp登录login")
    @ApiOperation(value = "tcp登录login", notes = "tcp登录login")
    @PostMapping(value = "/login")
    public Result<?> login(@RequestBody TcpLoginRequest loginRequest) throws InterruptedException {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("name", loginRequest.getUsername());
        MSC msc = mSCService.getOne(queryWrapper);
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            //登录名称
            message.setMessageType(MessageTypeEnum.LOGIN.getValue());
            //登录序列号
            message.setMessageSerialNo(0x11);
            //用户名
            byte[] userBytes = SendMessageUtils.padWithSpaces(msc.getName(), AttributeLength.USER_LENGTH.getLength());
            byte[] bytes = SendMessageUtils.padWithSpaces(loginRequest.getPassword(), AttributeLength.PASSWORD_LEN.getLength());
            ByteBuffer buffer = ByteBuffer.allocate(userBytes.length + bytes.length);
            buffer.put(userBytes).put(bytes);
            message.setMessageContent(buffer.array());
            channel.writeAndFlush(message);
            //获取对应的字节
        } else {
            //直接再次链接
            NettyClient.start(msc);
        }
        //获取激活管道
        NettyClient.start(msc);
        return Result.OK("登录成功");
    }

    @AutoLog(value = "tcp登录login登出")
    @ApiOperation(value = "tcp登录login登出", notes = "tcp登录login登出")
    @PostMapping(value = "/loginout")
    public Result<?> loginout(@RequestBody TcpLoginRequest loginRequest) {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            //登录名称
            message.setMessageType(MessageTypeEnum.LOGOUT.getValue());
            //登录序列号
            message.setMessageSerialNo(0x11);
            channel.writeAndFlush(message);
            //获取对应的字节
        }
        return Result.OK("登出成功");

    }


    @AutoLog(value = "设置实时数据的访问方式")
    @ApiOperation(value = "设置实时数据的访问方式", notes = "设置实时数据的访问方式")
    @PostMapping(value = "/setWay")
    public Result<?> setWay(@RequestBody TcpLoginRequest loginRequest) {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            //登录名称
            message.setMessageType(MessageTypeEnum.SET_DYN_ACCESC_MODE.getValue());

            //开始组装发送内容
            byte[] terminalIDBytes = SendMessageUtils.padWithSpaces(msc.getTerminalID(), AttributeLength.SCID_LEN.getLength());
            byte[] groupIdBytes = SendMessageUtils.padWithSpaces(msc.getGroupId(), AttributeLength.LONG_LENGTH.getLength());
            byte[] wayBytes = SendMessageUtils.padWithSpaces(loginRequest.getWay(), AttributeLength.LONG_LENGTH.getLength());
            //定时发送时需要设置时间间隔
            byte[] pollingTimeBytes = SendMessageUtils.padWithSpaces(loginRequest.getPollingTime() + "", AttributeLength.LONG_LENGTH.getLength());
            String[] dataIds = loginRequest.getDataIds();
            byte[] dataCntBytes = null;
            if (dataIds == null) {
                dataCntBytes = SendMessageUtils.padWithSpaces("0", AttributeLength.LONG_LENGTH.getLength());
            } else {
                dataCntBytes = SendMessageUtils.padWithSpaces(dataIds.length + "", AttributeLength.LONG_LENGTH.getLength());
            }
            ByteBuffer buffer = ByteBuffer.allocate(terminalIDBytes.length + groupIdBytes.length + wayBytes.length + pollingTimeBytes.length + dataCntBytes.length * AttributeLength.ID_LEN.getLength());
            //根据数量组装ids
            buffer.put(terminalIDBytes).put(groupIdBytes).put(wayBytes).put(pollingTimeBytes).put(dataCntBytes);
            for (String dataId : dataIds) {
                byte[] dataIdBytes = SendMessageUtils.padWithSpaces(dataId, AttributeLength.ID_LEN.getLength());
                buffer.put(dataIdBytes);
            }
            message.setMessageContent(buffer.array());
            //登录序列号
            message.setMessageSerialNo(0x11);
            channel.writeAndFlush(message);
            //获取对应的字节
        }
        return Result.OK("登出成功");

    }

    @AutoLog(value = "用户请求告警信息")
    @ApiOperation(value = "用户请求告警信息", notes = "用户请求告警信息")
    @PostMapping(value = "/setAlarmWay")
    public Result<?> setAlarmWay(@RequestBody TcpLoginRequest loginRequest) {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            //登录名称
            message.setMessageType(MessageTypeEnum.SET_ALARM_MODE.getValue());
            //开始组装发送内容

            byte[] groupIdBytes = SendMessageUtils.padWithSpaces(msc.getGroupId(), AttributeLength.LONG_LENGTH.getLength());
            byte[] wayBytes = SendMessageUtils.padWithSpaces(loginRequest.getMode(), AttributeLength.LONG_LENGTH.getLength());
            //定时发送时需要设置时间间隔

            String[] dataIds = loginRequest.getDataIds();
            byte[] dataCntBytes = null;
            if (dataIds == null) {
                dataCntBytes = SendMessageUtils.padWithSpaces("0", AttributeLength.LONG_LENGTH.getLength());
            } else {
                dataCntBytes = SendMessageUtils.padWithSpaces(dataIds.length + "", AttributeLength.LONG_LENGTH.getLength());
            }
            ByteBuffer buffer = ByteBuffer.allocate(groupIdBytes.length + wayBytes.length + dataCntBytes.length * AttributeLength.ID_LEN.getLength());
            //根据数量组装ids
            buffer.put(groupIdBytes).put(wayBytes).put(dataCntBytes);
            for (String dataId : dataIds) {
                byte[] dataIdBytes = SendMessageUtils.padWithSpaces(dataId, AttributeLength.ID_LEN.getLength());
                buffer.put(dataIdBytes);
            }
            message.setMessageContent(buffer.array());
            //登录序列号
            message.setMessageSerialNo(0x11);
            channel.writeAndFlush(message);
            //获取对应的字节
        }
        return Result.OK("登出成功");

    }


    /**
     * 添加
     *
     * @param
     * @return
     */
    @AutoLog(value = "tcp用户请求写监控点")
    @ApiOperation(value = "tcp用户请求写监控点", notes = "tcp用户请求写监控点")
    @PostMapping(value = "/setPort")
    public Result<?> setPort(@RequestBody TcpLoginRequest loginRequest) throws InterruptedException {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //获取激活管道
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            message.setMessageType(MessageTypeEnum.SET_POINT.getValue());
            byte[] bytes = SendMessageUtils.padWithSpaces(loginRequest.getDataId(), AttributeLength.ID_LEN.getLength());
            ByteBuffer buffer = ByteBuffer.allocate(AttributeLength.ID_LEN.getLength());
            buffer.put(bytes);
            message.setMessageContent(buffer.array());
            channel.writeAndFlush(message);
        }
        return Result.OK("tcp用户请求写监控点");
    }

    /**
     * 添加
     *
     * @param
     * @return
     */
    @AutoLog(value = "tcp用户请求改口令")
    @ApiOperation(value = "tcp用户请求改口令", notes = "tcp用户请求改口令")
    @PostMapping(value = "/modifyPa")
    public Result<?> modifyPa(@RequestBody TcpLoginRequest loginRequest) throws InterruptedException {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //获取激活管道
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            message.setMessageType(MessageTypeEnum.MODIFY_PA.getValue());
            ByteBuffer buffer = ByteBuffer.allocate(AttributeLength.USER_LENGTH.getLength() + AttributeLength.PASSWORD_LEN.getLength() * 2);
            byte[] username = SendMessageUtils.padWithSpaces(loginRequest.getUsername(), AttributeLength.USER_LENGTH.getLength());
            byte[] password = SendMessageUtils.padWithSpaces(loginRequest.getPassword(), AttributeLength.PASSWORD_LEN.getLength());
            byte[] newPassword = SendMessageUtils.padWithSpaces(loginRequest.getNewPassword(), AttributeLength.PASSWORD_LEN.getLength());
            buffer.put(username).put(password).put(newPassword);
            message.setMessageContent(buffer.array());
            channel.writeAndFlush(message);
        }
        return Result.OK("tcp用户请求改口令成功");
    }


    /**
     * 添加
     *
     * @param
     * @return
     */
    @AutoLog(value = "tcp时钟同步")
    @ApiOperation(value = "tcp时钟同步", notes = "tcp时钟同步")
    @PostMapping(value = "/timeCheck")
    public Result<?> timeCheck(@RequestBody TcpLoginRequest loginRequest) throws InterruptedException {
        //根据请求参数，生成登录参数
        //根据登录的用户名获取sc
        MSC msc = mSCService.getById(loginRequest.getUsername());
        //获取激活管道
        //根据msc获取管道
        Channel channel = channelManager.getChannel(msc.getScid());
        if (channel != null) {
            Message message = new Message();
            message.setMessageType(MessageTypeEnum.TIME_CHECK.getValue());
            //获取当前时间的年月日时分秒
            Date now = new Date();
            int year = now.getYear();
            int month = now.getMonth();
            int day = now.getDay();
            int hour = now.getHours();
            int minute = now.getMinutes();
            int second = now.getSeconds();
            byte[] yearBytes = SendMessageUtils.padWithSpaces(String.valueOf(year), AttributeLength.SHORT_LENGTH.getLength());
            byte[] monthBytes = SendMessageUtils.padWithSpaces(String.valueOf(month), AttributeLength.CHAR_LENGTH.getLength());
            byte[] dayBytes = SendMessageUtils.padWithSpaces(String.valueOf(day), AttributeLength.CHAR_LENGTH.getLength());
            byte[] hourBytes = SendMessageUtils.padWithSpaces(String.valueOf(hour), AttributeLength.CHAR_LENGTH.getLength());
            byte[] minuteBytes = SendMessageUtils.padWithSpaces(String.valueOf(minute), AttributeLength.CHAR_LENGTH.getLength());
            byte[] secondBytes = SendMessageUtils.padWithSpaces(String.valueOf(second), AttributeLength.CHAR_LENGTH.getLength());
            ByteBuffer buffer = ByteBuffer.allocate(AttributeLength.SHORT_LENGTH.getLength() + AttributeLength.CHAR_LENGTH.getLength() * 5);
            buffer.put(yearBytes).put(monthBytes).put(dayBytes).put(hourBytes).put(minuteBytes).put(secondBytes);
            message.setMessageContent(buffer.array());
            channel.writeAndFlush(message);
        }
        return Result.OK("tcp用户请求改口令成功");
    }

    /**
     * 编辑
     *
     * @param dActiveAlarm
     * @return
     */
    @AutoLog(value = "实时告警管理-编辑")
    @ApiOperation(value = "实时告警管理-编辑", notes = "实时告警管理-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<?> edit(@RequestBody DActiveAlarm dActiveAlarm) {
        dActiveAlarmService.updateById(dActiveAlarm);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "实时告警管理-通过id删除")
    @ApiOperation(value = "实时告警管理-通过id删除", notes = "实时告警管理-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        dActiveAlarmService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "实时告警管理-批量删除")
    @ApiOperation(value = "实时告警管理-批量删除", notes = "实时告警管理-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.dActiveAlarmService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功！");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "实时告警管理-通过id查询")
    @ApiOperation(value = "实时告警管理-通过id查询", notes = "实时告警管理-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        DActiveAlarm dActiveAlarm = dActiveAlarmService.getById(id);
        return Result.OK(dActiveAlarm);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param dActiveAlarm
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, DActiveAlarm dActiveAlarm) {
        return super.exportXls(request, dActiveAlarm, DActiveAlarm.class, "实时告警管理");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, DActiveAlarm.class);
    }

}
